/**
 * 
 */
package com.fnic.pearl.scheduler.action;

import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.fnic.pearl.scheduler.constant.CondHeaderField;
import com.fnic.pearl.scheduler.constant.TestTaskStatus;
import com.fnic.pearl.scheduler.dao.SchedulerStore;
import com.fnic.pearl.scheduler.mod.ProbeStatusManager;
import com.fnic.pearl.scheduler.model.ProbeStatus;
import com.fnic.pearl.scheduler.model.ProbeTaskStatus;
import com.fnic.pearl.scheduler.model.TestTask;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * 处理 探针的测试任务状态
 * 
 * @author HuHaiyang
 * @date 2013年7月14日
 */
public class ProbeTestTaskStatusServlet extends HttpServlet
{
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(ProbeTestTaskStatusServlet.class);
    private Gson gson = new GsonBuilder()
                    .excludeFieldsWithoutExposeAnnotation()
                    .setDateFormat("yyyy-MM-dd HH:mm:ss")
                    .create();

    /**
     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        String[] values = request.getParameterValues(CondHeaderField.COND_PROBE_ID);
        if (values == null || values.length != 1)
        {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        int probeId = 0;
        try
        {
            probeId = Integer.valueOf(values[0]);
        }
        catch (NumberFormatException e)
        {
            LOG.warn("probeId format error: " + e.getMessage());
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        ProbeStatus ps = ProbeStatusManager.getInstance().get(probeId);
        if (ps == null || ps.getStatus() != ProbeStatus.S_LOGIN)
        {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return ;
        }
        
        ProbeTaskStatus pts = null;
        try
        {
            pts = gson.fromJson(new InputStreamReader(
                    request.getInputStream()), ProbeTaskStatus.class);
        }
        catch (Exception e)
        {
            LOG.warn("probe task status parse exception - " + e.getMessage());
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        if (pts == null)
        {
            LOG.warn("probe tasks status is null!");
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        pts.setProbeId(probeId);
        TestTask tt = SchedulerStore.getInstance().getTestTask(pts.getTaskId());
        if (tt == null)
        {
            LOG.warn("can not find task of probe task status: " + pts);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        // 先从老的任务队列中退出
        switch (tt.getStatus())
        {
        case TestTaskStatus.S_ISSUED:
            SchedulerStore.getInstance().popIssuedTestTask(
                    pts.getProbeId(), pts.getTaskId());
            break;
            
        case TestTaskStatus.S_RUNNING:
            SchedulerStore.getInstance().popRunningTestTask(
                    pts.getProbeId(), pts.getTaskId());
            break;
            
        case TestTaskStatus.S_EXEC_SUCC:
            SchedulerStore.getInstance().popExecSuccTestTask(
                    probeId, pts.getTaskId());
            break;
        }
        
        // 更新任务的状态为新的（从 探针 上报的状态）
        // 并添加到新的状态对应的 队列中
        switch (pts.getStatus())
        {
        case TestTaskStatus.S_RUNNING:
            SchedulerStore.getInstance().updateTestTaskStatus(tt, pts.getStatus());
            SchedulerStore.getInstance().putRunningTestTask(tt);
            break;
            
        case TestTaskStatus.S_EXEC_SUCC:
            SchedulerStore.getInstance().updateTestTaskStatus(tt, pts.getStatus());
            SchedulerStore.getInstance().putExecSuccTestTask(tt);
            break;
            
        case TestTaskStatus.S_ISSUE_ES_SUCC:
        case TestTaskStatus.S_ISSUE_REDIS_SUCC:
        case TestTaskStatus.S_FAILED_TASK_PARSE:
        case TestTaskStatus.S_FAILED_TASK_EXEC:
        case TestTaskStatus.S_FAILED_RESULT_ISSUE:
        case TestTaskStatus.S_FAILED_ISSUE_REDIS:
            SchedulerStore.getInstance().updateTestTaskStatus(tt, pts.getStatus());
            SchedulerStore.getInstance().putSFHTestTask(tt);
            break;
            
        default:
            LOG.warn("unsupport probe task status: " + pts);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return ;
        }
        
        SchedulerStore.getInstance().putTestTaskStatus(pts);
        
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
    }
}
